package cn.trigram.mgb.mixed_simple_dynamic;

import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

public class MixedDynamicSqlPlugin extends PluginAdapter {

  @Override
  public boolean validate(List<String> warnings) {

    return true;
  }

  @Override
  public boolean clientGenerated(
      Interface interfaze, IntrospectedTable introspectedTable
  ) {

    interfaze.getAnnotations().remove("@Mapper");
    interfaze.getImportedTypes().remove(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
    return true;
  }

  @Override
  public boolean clientBasicSelectManyMethodGenerated(
      Method method, Interface interfaze, IntrospectedTable introspectedTable
  ) {

    List<String> annotations = new ArrayList<>();
    annotations.add(method.getAnnotations().get(0));
    annotations.add(method.getAnnotations().get(1));
    annotations.add("@ResultMap(\"BaseResultMap\")");
    method.getAnnotations().clear();
    method.getAnnotations().addAll(annotations);
    return super.clientBasicSelectManyMethodGenerated(method, interfaze, introspectedTable);
  }

  @Override
  public boolean clientBasicSelectOneMethodGenerated(
      Method method, Interface interfaze, IntrospectedTable introspectedTable
  ) {

    method.getAnnotations().remove(2);
    method.getAnnotations().add("@ResultMap(\"BaseResultMap\")");
    return super.clientBasicSelectOneMethodGenerated(method, interfaze, introspectedTable);
  }

  @Override
  public boolean dynamicSqlSupportGenerated(TopLevelClass supportClass, IntrospectedTable introspectedTable) {

    String tableName = introspectedTable.getFullyQualifiedTableNameAtRuntime();
    String schema    = introspectedTable.getFullyQualifiedTable().getIntrospectedSchema();
    String fullTableName = Lists.newArrayList(
            schema,
            tableName
        )
        .stream().filter(StringUtils::isNotBlank).collect(Collectors.joining("."));
    supportClass.getInnerClasses().forEach(innerClass ->
        innerClass.getMethods().forEach(method ->
            {
              List<String> bodyLines = method.getBodyLines();
              for (int i = 0; i < bodyLines.size(); i++) {
                String body = bodyLines.get(i);
                bodyLines.set(i, body.replace(tableName, fullTableName));
              }
            }
        )
    );
    return true;
  }

}
